from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, timedelta
from flask import render_template
import os

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///weather.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

# 数据模型定义
class City(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    country = db.Column(db.String(50))
    weather_records = db.relationship('Weather', backref='city', lazy=True)
    forecast_records = db.relationship('Forecast', backref='city', lazy=True)

class Weather(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    city_id = db.Column(db.Integer, db.ForeignKey('city.id'), nullable=False)
    temperature = db.Column(db.Float)
    humidity = db.Column(db.Integer)
    wind_speed = db.Column(db.Float)
    condition = db.Column(db.String(50))
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

class Forecast(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    city_id = db.Column(db.Integer, db.ForeignKey('city.id'), nullable=False)
    date = db.Column(db.DateTime)
    temperature_min = db.Column(db.Float)
    temperature_max = db.Column(db.Float)
    condition = db.Column(db.String(50))

# API路由定义
@app.route('/api/v1/weather', methods=['GET'])
def get_weather():
    city_name = request.args.get('city')
    city_id = request.args.get('city_id')

    if not city_name and not city_id:
        return jsonify({"error": "City name or ID is required"}), 400

    query = City.query
    if city_name:
        query = query.filter_by(name=city_name)
    else:
        query = query.filter_by(id=city_id)

    city = query.first()
    if not city:
        return jsonify({"error": "City not found"}), 404

    weather = Weather.query.filter_by(city_id=city.id).order_by(Weather.timestamp.desc()).first()
    if not weather:
        return jsonify({"error": "Weather data not available"}), 404

    result = {
        "city": city.name,
        "country": city.country,
        "temperature": weather.temperature,
        "humidity": weather.humidity,
        "wind_speed": weather.wind_speed,
        "condition": weather.condition,
        "timestamp": weather.timestamp.strftime('%Y-%m-%d %H:%M:%S')
    }

    return jsonify(result)

@app.route('/api/v1/forecast', methods=['GET'])
def get_forecast():
    city_name = request.args.get('city')
    city_id = request.args.get('city_id')
    days = int(request.args.get('days', 5))

    if not city_name and not city_id:
        return jsonify({"error": "City name or ID is required"}), 400
    if days < 1 or days > 10:
        return jsonify({"error": "Days must be between 1 and 10"}), 400

    query = City.query
    if city_name:
        query = query.filter_by(name=city_name)
    else:
        query = query.filter_by(id=city_id)

    city = query.first()
    if not city:
        return jsonify({"error": "City not found"}), 404

    today = datetime.utcnow().date()
    forecast_days = []
    for i in range(days):
        date = today + timedelta(days=i)
        forecast = Forecast.query.filter_by(
            city_id=city.id,
            date=datetime.combine(date, datetime.min.time())
        ).first()

        if forecast:
            forecast_days.append({
                "date": date.strftime('%Y-%m-%d'),
                "temperature_min": forecast.temperature_min,
                "temperature_max": forecast.temperature_max,
                "condition": forecast.condition
            })

    result = {
        "city": city.name,
        "country": city.country,
        "forecast": forecast_days
    }

    return jsonify(result)

@app.route('/api/v1/cities', methods=['GET'])
def get_cities():
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 20))

    cities = City.query.paginate(page=page, per_page=per_page, error_out=False)

    result = {
        "page": page,
        "per_page": per_page,
        "total_pages": cities.pages,
        "total_items": cities.total,
        "cities": [{
            "id": city.id,
            "name": city.name,
            "country": city.country
        } for city in cities.items]
    }

    return jsonify(result)
@app.route('/')
def index():
    return render_template('index.html')

def init_test_data():
    city1 = City(name="北京", country="中国")
    city2 = City(name="上海", country="中国")
    city3 = City(name="广州", country="中国")
    db.session.add_all([city1, city2, city3])
    db.session.commit()

    weather1 = Weather(
        city_id=city1.id,
        temperature=25.5,
        humidity=60,
        wind_speed=3.2,
        condition="晴朗"
    )
    weather2 = Weather(
        city_id=city2.id,
        temperature=28.0,
        humidity=75,
        wind_speed=4.5,
        condition="多云"
    )
    db.session.add_all([weather1, weather2])
    db.session.commit()

    today = datetime.utcnow().date()
    for i in range(5):
        date = today + timedelta(days=i)
        forecast1 = Forecast(
            city_id=city1.id,
            date=datetime.combine(date, datetime.min.time()),
            temperature_min=20.0 + i,
            temperature_max=28.0 + i,
            condition=["晴朗", "多云", "小雨", "晴朗", "多云"][i]
        )
        db.session.add(forecast1)
    db.session.commit()

if __name__ == '__main__':
    with app.app_context():
        if not os.path.exists('weather.db'):
            db.create_all()
            init_test_data()
    app.run(debug=True)
